﻿using FPSO.HMI.Utils;
using FPSO.HMI.Views.Dialog;
using FPSO.Models;
using FPSO.Models.Constant;
using FPSO.Models.Domain;
using FPSO.Services;
using FPSO.Services.Impl;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace FPSO.HMI.Controls
{
    /// <summary>
    /// UCTaskQueueEx.xaml 的交互逻辑
    /// </summary>
    public partial class UCTaskQueueEx : UserControl
    {
        private List<int> loadQueueIds;
        private ITankLevelService tankLevelService;

        public UCTaskQueueEx()
        {
            InitializeComponent();
            loadQueueIds = new List<int>();
            loadQueueIds.Add(TaskQueueConstant.LOAD_TASK_1_ID);
            loadQueueIds.Add(TaskQueueConstant.LOAD_TASK_2_ID);
            TaskService = null;

            tankLevelService = new ImitateTankLevelService();
        }

        [Category("Action")]
        [Description("添加任务")]
        public event Action<object, int> AddTaskAction;

        [Category("Action")]
        [Description("开始模拟")]
        public event Action<object> StartImitateAction;

        [Category("Action")]
        [Description("暂停模拟")]
        public event Action<object,int> PauseImitateAction;

        [Category("Action")]
        [Description("提交模拟")]
        public event Action<object,int> SubmitTaskAction;

        [Category("Action")]
        [Description("自动生成任务")]
        public event Action<object, int> AutoTaskAction;

		[Category("Action")]
		[Description("定义初始状态")]
		public event Action<object, int> DefineStatusAction;

		public ITankTaskService TaskService { get; set; }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);
            ControlUpdate();  //Tips：舱室装载任务记录在MYSQL的t_task表中
        }

        public static void RenderUpdateByPropertyChanged(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
        {
            if (dependency is UCTaskQueueEx uctask)
            {
                uctask.ControlUpdate();
            }
        }

        public static void RenderUpdateByCurrentTimeChanged(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
        {
            if (dependency is UCTaskQueueEx uctask)
            {
                uctask.MoveCurrentLine();
            }
        }

        public double getRealRate(String tankId,double volume)
        {
            string tankName = TankConstant.GetTankName(tankId);
            
            SafeLoadAlgorithmService safeloadAlgorithm = SafeLoadAlgorithmService.GetInstance();
            //Tips：C++端接口新增SingleTank计算方法，每次仅支持单一舱室的计算，详见《C++端接口调用说明》
            string inputstr = "{Manual}#{volume}#{" + string.Join("#", tankName, volume.ToString() + "#}");

            ManualCalcResult result = safeloadAlgorithm.CallPipeSingleCalc(inputstr, tankId);
            if (result != null)
            {
                //Tips：其余控件赋值来源于接口计算结果
                TankCalcState tankState = result.GetTankCalcState(tankId);
                return tankState.Rate;
            }

            return 0.0;
        }

		/// <summary>
		/// ControlUpdateByRate用于通过实际舱室流速修正任务时间轴
		/// </summary>
		/// <param name="nowTankVolume"></param>
		//public void ControlUpdateByRate(Dictionary<string,double> nowTankVolume)
		public void ControlUpdateByRate(ManualCalcResult calcResult)
		{
            List<TankTask> allTaskList = null;
            if (CanEditTask)
            {
                allTaskList = TaskService.GetAllWaitingAndCheckingTaskList();
            }
            else
            {
                allTaskList = TaskService.GetAllWaitAndExecingTaskList();
            }

			if(allTaskList != null)
			{
				var sortTaskList = allTaskList.OrderBy(o => o.PlanStartTime).ToList();

				double hourLong = 0;
				for (int i = 0; i < sortTaskList.Count; i++)
				{
					TankTask tankTask = sortTaskList[i];
					if (i == 0)
					{
						TankCalcState tankCalcState = calcResult.GetTankCalcState(tankTask.TankId);
						double tankVolume = tankCalcState.Volume;
						double realRate = tankCalcState.Rate;
						//double tankVolume = nowTankVolume[tankTask.TankId];
						//double realRate = getRealRate(tankTask.TankId, tankVolume);
						if (realRate > 0)
						{
							hourLong = Math.Abs(tankTask.TargetVolm /*/ 100 * TankConstant.GetTankVolume(tankTask.TankId)*/ - tankVolume) / realRate;

							foreach (WBTTask wBTTask in tankTask.WBTTaskList)
							{
								//double wbtTankVolume = nowTankVolume[wBTTask.WBTTankId];
								//double wbtRealRate = getRealRate(wBTTask.WBTTankId, wbtTankVolume);
								TankCalcState wbtCalcState = calcResult.GetTankCalcState(wBTTask.WBTTankId);
								double wbtTankVolume = wbtCalcState.Volume;
								double wbtRealRate = wbtCalcState.Rate;
								if(Math.Abs(wbtRealRate) > 0)
								{
									double wbtHourLong = Math.Abs(wBTTask.TargetVolume /*/ 100 * TankConstant.GetTankVolume(wBTTask.WBTTankId)*/ - wbtTankVolume) / wbtRealRate;
									if (wbtHourLong > hourLong) 
										hourLong = wbtHourLong;
								}
							}
							tankTask.PlanEndTime = tankTask.PlanStartTime;
							tankTask.PlanEndTime = tankTask.PlanEndTime.AddHours(hourLong);
						}
					}
					else
					{
						tankTask.PlanStartTime = tankTask.PlanStartTime.AddHours(hourLong);
						tankTask.PlanEndTime = tankTask.PlanEndTime.AddHours(hourLong);
					}

					TaskService.UpdateTask(tankTask);
				}
				ControlUpdate();
			}
		}

		/// <summary>
		/// ControlStatusUpdate通过当前实际液位和任务中各液舱的对比确定舱室装卸载控制状态
		/// </summary>
		/// <param name="nowTankVolume"></param>
		public void ControlStatusUpdate(Dictionary<string, double> nowTankVolume, Dictionary<string, int> currentTankCtrlStatus)
		{
			List<TankTask> allExecTaskList = TaskService.GetAllExecingTaskList();
			List<TankTask> allWaitTaskList = TaskService.GetAllWaitTaskList();

			foreach(TankTask tankTask in allExecTaskList)
			{
				string tankid = tankTask.TankId;
				int tasktype = tankTask.TaskType;
				double tarVol = tankTask.TargetVolm;

				double curVol = nowTankVolume[tankid];
				//装载过程 卸载过程
				//-1为停止指令
				if((tasktype == 0 && curVol >= tarVol)
					|| (tasktype == 1 && curVol <= tarVol))
				{
					currentTankCtrlStatus[tankid] = -1;
				}
			}

			//根据任务启动类型判断当前等待任务是否需要开启
			//如是根据时间标定是否启动，则通过当前时间和预计启动时间对比
			//如是基于前序任务完成后启动，则查询前序任务状态，如完成则启动
			//启动标识为1
			foreach (TankTask tankTask in allWaitTaskList)
			{

				string tankid = tankTask.TankId;
				int tasktype = tankTask.TaskType;
				double tarVol = tankTask.TargetVolm;

				double curVol = nowTankVolume[tankid];
				//装载过程 卸载过程
				//-1为停止指令
				if ((tasktype == 0 && curVol >= tarVol)
					|| (tasktype == 1 && curVol <= tarVol))
				{
					currentTankCtrlStatus[tankid] = -1;
				}

			}
		}
		public void ControlUpdate()
        {
            if (ActualHeight < 30 || ActualWidth < 200)
                return;

            if (TaskService == null)
                return;

            List<TankTask> allTaskList = null;

            if (CanEditTask)
            {
                allTaskList = TaskService.GetAllWaitingAndCheckingTaskList();
            }
            else
            {
                allTaskList = TaskService.GetAllWaitAndExecingTaskList();
            }
            //确定StartTime
			if(allTaskList != null)
			{
				TankTask firstTask = allTaskList.FirstOrDefault();
				if (firstTask != null && firstTask.PlanStartTime < DateTime.Now)
				{
					StartTime = Convert.ToDateTime(allTaskList.FirstOrDefault().PlanStartTime.ToString("yyyy-MM-dd HH:00:00"));
				}
				else
				{
					StartTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:00:00"));
				}
			}

			lineHeight = 20;
            DrawBackground();

            List<Canvas> c1List = new List<Canvas>() { canvas_0_0, canvas_1_0 };
            List<Canvas> c2List = new List<Canvas>() { canvas_0_1, canvas_1_1 };

            for (int i = 0; i < loadQueueIds.Count; i++)
            {
                Canvas c1 = c1List[i];
                Canvas c2 = c2List[i];

                c1.Children.Clear();
                c2.Children.Clear();

                double maxPos = 0;

                if (TaskService != null)
                {
					//List<TankTask> taskList = TaskService.GetWaitAndExecingTaskList(loadQueueIds[i]);
					if (allTaskList != null)
					{
						List<TankTask> taskList = allTaskList.Where(t => t.TaskQueueId == loadQueueIds[i]).ToList();
						foreach (TankTask task in taskList)
						{
							Grid taskgrid = CreateTaskGrid(task);
							double leftPos = CalcLeftPosByTime(task.PlanStartTime);
							if (leftPos >= maxPos)
							{
								c1.Children.Add(taskgrid);
								if (maxPos < leftPos + taskgrid.Width)
								{
									maxPos = leftPos + taskgrid.Width;
								}
							}
							else
							{
								c2.Children.Add(taskgrid);
							}

							Canvas.SetLeft(taskgrid, leftPos);
							Canvas.SetTop(taskgrid, 0);
						}

					}
				}
            }

            //倒仓和外输任务
            if (TaskService != null)
            {
                canvas_2_0.Children.Clear();
                canvas_2_1.Children.Clear();
                canvas_2_2.Children.Clear();

                double max1Pos = 0;
                double max2Pos = 0;
				if (allTaskList != null)
				{
					//List<TankTask> taskList = TaskService.GetWaitAndExecingTaskList(TaskQueueConstant.UNLOAD_TASK_1_ID);
					List<TankTask> taskList = allTaskList.Where(t => t.TaskQueueId == TaskQueueConstant.UNLOAD_TASK_1_ID).ToList();
					foreach (TankTask task in taskList)
					{
						Grid taskgrid = CreateOutOrSwapTaskGrid(task);
						double leftPos = CalcLeftPosByTime(task.PlanStartTime);
						if (leftPos >= max1Pos)
						{
							canvas_2_0.Children.Add(taskgrid);
							if (max1Pos < leftPos + taskgrid.Width)
							{
								max1Pos = leftPos + taskgrid.Width;
							}
						}
						else if (leftPos >= max2Pos)
						{
							canvas_2_1.Children.Add(taskgrid);
							if (max2Pos < leftPos + taskgrid.Width)
							{
								max2Pos = leftPos + taskgrid.Width;
							}
						}
						else
						{
							canvas_2_2.Children.Add(taskgrid);
						}

						Canvas.SetLeft(taskgrid, leftPos);
						Canvas.SetTop(taskgrid, 0);
					}
				}
            }

            DrawCurrentLine();
        }

        public static readonly DependencyProperty StartTimeProperty =
            DependencyProperty.Register("StartTime", typeof(DateTime), typeof(UCTaskQueueEx),
                new PropertyMetadata(DateTime.Now, new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime StartTime
        {
            get { return (DateTime)GetValue(StartTimeProperty); }
            set { SetValue(StartTimeProperty, value); }
        }

        public static readonly DependencyProperty CurrentTimeProperty =
            DependencyProperty.Register("CurrentTime", typeof(DateTime), typeof(UCTaskQueueEx),
                new PropertyMetadata(DateTime.Now, new PropertyChangedCallback(RenderUpdateByCurrentTimeChanged)));
        /// <summary>
        /// 当前时间
        /// </summary>
        public DateTime CurrentTime
        {
            get { return (DateTime)GetValue(CurrentTimeProperty); }
            set { SetValue(CurrentTimeProperty, value); }
        }

        public static readonly DependencyProperty CanEditTaskProperty =
            DependencyProperty.Register("CanEditTask", typeof(bool), typeof(UCTaskQueueEx), new PropertyMetadata(false));
        /// <summary>
        /// 是否能够修改任务
        /// </summary>
        public bool CanEditTask
        {
            get { return (bool)GetValue(CanEditTaskProperty); }
            set { SetValue(CanEditTaskProperty, value); }
        }

		/// <summary>
		/// HourCount中PropertyMetadata第一个参数为甘特图的缺省长度，应为动态调整，在实际演示时采用3小时
		/// </summary>
		public static readonly DependencyProperty HourCountProperty =
            DependencyProperty.Register("HourCount", typeof(int), typeof(UCTaskQueueEx),
                new PropertyMetadata(24, new PropertyChangedCallback(RenderUpdateByPropertyChanged)));
        /// <summary>
        /// 小时数
        /// </summary>
        public int HourCount
        {
            get { return (int)GetValue(HourCountProperty); }
            set { SetValue(HourCountProperty, value); }
        }

        /// <summary>
        /// （日期和时间）行高
        /// </summary>
        private double lineHeight;

        private void DrawBackground()
        {
            bgCanvas.Children.Clear();
            Thickness lblPad = new Thickness(0);
            Brush borderBrush = new SolidColorBrush(Colors.White);
            double hourWidth = bgCanvas.ActualWidth / HourCount;
            DoubleCollection dashArray = DoubleCollection.Parse("2,3");
            for (int i = 0; i < HourCount; i++)
            {
                DateTime hourTime = StartTime.AddHours(i);

                if (hourTime.Hour == 0 || i == 0)
                {
                    Line lineDay = new Line();
                    lineDay.Stroke = borderBrush;
                    lineDay.StrokeThickness = BorderThickness.Right;
                    lineDay.X1 = i * hourWidth;
                    lineDay.X2 = i * hourWidth;
                    lineDay.Y1 = 0;
                    lineDay.Y2 = bgCanvas.ActualHeight;
                    bgCanvas.Children.Add(lineDay);

                    Label lblDay = new Label();
                    lblDay.Foreground = this.Foreground;
                    lblDay.Content = hourTime.ToString("yyyy-MM-dd");
                    lblDay.Width = hourWidth * (Math.Min(24, HourCount - i)/* - hourTime.Hour*/);
                    lblDay.Height = lineHeight;
                    lblDay.HorizontalContentAlignment = HorizontalAlignment.Center;
                    lblDay.VerticalContentAlignment = VerticalAlignment.Center;
                    lblDay.Padding = lblPad;
                    bgCanvas.Children.Add(lblDay);
                    lblDay.SetValue(Canvas.LeftProperty, i * hourWidth);
                    lblDay.SetValue(Canvas.TopProperty, 0d);
                }
                else
                {
                    Line lineHour = new Line();
                    lineHour.Stroke = borderBrush;
                    lineHour.StrokeThickness = BorderThickness.Right;
                    lineHour.X1 = i * hourWidth;
                    lineHour.X2 = i * hourWidth;
                    lineHour.Y1 = lineHeight;
                    lineHour.Y2 = bgCanvas.ActualHeight;
                    lineHour.StrokeDashArray = dashArray;
                    bgCanvas.Children.Add(lineHour);
                }

                Label lblHour = new Label();
                lblHour.Foreground = this.Foreground;
                lblHour.Content = hourTime.Hour.ToString();
                lblHour.Width = hourWidth;
                lblHour.Height = lineHeight;
                lblHour.HorizontalContentAlignment = HorizontalAlignment.Center;
                lblHour.VerticalContentAlignment = VerticalAlignment.Center;
                lblHour.Padding = lblPad;
                bgCanvas.Children.Add(lblHour);
                lblHour.SetValue(Canvas.LeftProperty, i * hourWidth);
                lblHour.SetValue(Canvas.TopProperty, lineHeight);
            }
        }

        private void DrawCurrentLine()
        {
            double xPos = CalcLeftPosByTime(CurrentTime);
            Point[] curPoints = new Point[]
            {
                new Point(0, currentCanvasContiner.ActualHeight - lineHeight),
                new Point(10, currentCanvasContiner.ActualHeight - lineHeight),
                new Point(5.5, currentCanvasContiner.ActualHeight - lineHeight - 4),
                new Point(5.5, 0),
                new Point(4.5, 0),
                new Point(4.5, currentCanvasContiner.ActualHeight - lineHeight - 4),
                new Point(0, currentCanvasContiner.ActualHeight - lineHeight)
            };
            polygonCurLine.Points = new PointCollection(curPoints);
            Canvas.SetTop(polygonCurLine, 0);
            Canvas.SetLeft(polygonCurLine, 60);
            txbCurTime.Text = CurrentTime.ToString("yyyy-MM-dd HH:mm:ss");
            Canvas.SetLeft(currentCanvas, xPos + (currentCanvasContiner.ActualWidth - canvas_0_0.ActualWidth) - 65);
        }

        private void MoveCurrentLine()
        {
            double xPos = CalcLeftPosByTime(CurrentTime);
            txbCurTime.Text = CurrentTime.ToString("yyyy-MM-dd HH:mm:ss");
            Canvas.SetLeft(currentCanvas, xPos + (currentCanvasContiner.ActualWidth - canvas_0_0.ActualWidth) - 65);
        }

        private double CalcLeftPosByTime(DateTime time)
        {
            DateTime minTime = DateTime.Parse(StartTime.ToString("yyyy-MM-dd HH:00:00"));
            double totalMinutes = (time - minTime).TotalMinutes;
            if (totalMinutes < 0 || totalMinutes > HourCount * 60)
            {
                return 0;
            }

            return totalMinutes * canvas_0_0.ActualWidth / (HourCount * 60);
        }


        private readonly Thickness _PadThickness = new Thickness(0.5);
        private readonly SolidColorBrush _COTBodyBrush = new SolidColorBrush(Color.FromRgb(0xF5, 0x65, 0x82));
        private readonly SolidColorBrush _COTBorderBrush = new SolidColorBrush(Color.FromRgb(0xAF, 0x11, 0x21));
        private readonly SolidColorBrush _WBTBodyBrush = new SolidColorBrush(Color.FromRgb(0x3B, 0xD0, 0xFB));
        private readonly SolidColorBrush _WBTBorderBrush = new SolidColorBrush(Color.FromRgb(0x19, 0x8C, 0xD9));
        private readonly Thickness _StartTimeMargin = new Thickness(2, 0, 0, 0);
        private readonly SolidColorBrush _OutTaskBodyBrush = new SolidColorBrush(Color.FromRgb(0xFA, 0x92, 0x18));
        private readonly SolidColorBrush _SwapTaskBodyBrush = new SolidColorBrush(Color.FromRgb(0xE2, 0x68, 0xA9));
        private readonly SolidColorBrush _btnSelectBrash = new SolidColorBrush(Color.FromRgb(0x00, 0xaa, 0x00));
        private readonly SolidColorBrush _btnUnSelectBrash = new SolidColorBrush(Color.FromRgb(0x00, 0x00, 0x00));

        private Grid CreateTaskGrid(TankTask task)
        {
            double taskHours = (task.PlanEndTime - task.PlanStartTime).TotalHours;

            //计算任务宽度
            Grid gridTask = new Grid();
            gridTask.Width = canvas_0_0.ActualWidth / HourCount * taskHours;
            gridTask.Height = canvas_0_0.ActualHeight;
            gridTask.Background = _COTBodyBrush;

			//增加压载舱任务
            if (task.WBTTaskList != null && task.WBTTaskList.Count > 0)
            {
                Label lblWbt = new Label();
                string wbtNames = string.Empty;
                foreach(WBTTask wbtTask in task.WBTTaskList)
                {
                    if (!string.IsNullOrEmpty(wbtNames))
                    {
                        wbtNames += ",";
                    }
                    wbtNames += TankConstant.GetTankName(wbtTask.WBTTankId);
                }
                lblWbt.Content = wbtNames;
                lblWbt.Background = _WBTBodyBrush;
                lblWbt.FontSize = FontSize;
                lblWbt.HorizontalAlignment = HorizontalAlignment.Center;
                lblWbt.VerticalAlignment = VerticalAlignment.Bottom;
                lblWbt.HorizontalContentAlignment = HorizontalAlignment.Center;
                lblWbt.Padding = _PadThickness;
                lblWbt.Margin = new Thickness(0, 0, 0, 0);
                //lblWbt.Width = (gridTask.Width-4);
                gridTask.Children.Add(lblWbt);
            }

			//增加液货舱目标装载率
			Label lblTankName = new Label();
            lblTankName.Content = TankConstant.GetTankName(task.TankId) + string.Format("  {0}%", task.TargetVolm);
            lblTankName.FontSize = 1.1 * FontSize;
            lblTankName.HorizontalAlignment = HorizontalAlignment.Center;
            lblTankName.VerticalAlignment = VerticalAlignment.Center;
            lblTankName.Margin = new Thickness(5, 0, 0, 0);
            lblTankName.Padding = _PadThickness;
            gridTask.Children.Add(lblTankName);

			//增加液货舱任务开始时间
			Label lblStartTime = new Label();
            lblStartTime.Content = task.PlanStartTime.ToString("HH:mm");
            lblStartTime.FontSize = FontSize;
            lblStartTime.HorizontalAlignment = HorizontalAlignment.Left;
            lblStartTime.VerticalAlignment = VerticalAlignment.Top;
            lblStartTime.Padding = _PadThickness;
            lblStartTime.Margin = _StartTimeMargin;
            gridTask.Children.Add(lblStartTime);

			//增加液货舱任务执行时间
			Label lblUseTime = new Label();
            lblUseTime.Content = string.Format("+{0:f1}H", taskHours);
            lblUseTime.FontSize = FontSize;
            lblUseTime.HorizontalAlignment = HorizontalAlignment.Right;
            lblUseTime.VerticalAlignment = VerticalAlignment.Top;
            lblUseTime.Padding = _PadThickness;
            lblUseTime.Margin = new Thickness(0, 0, 2, 0);
            gridTask.Children.Add(lblUseTime);

			//增加液货舱任务目标容积
			double volmValue = (task.TargetVolm / 100d) * TankConstant.GetTankVolume(task.TankId);
			Label lblTargetVolm = new Label();
			lblTargetVolm.Content = string.Format("{0:f1}M3", volmValue);
			lblTargetVolm.FontSize = FontSize;
			lblTargetVolm.HorizontalAlignment = HorizontalAlignment.Center;
			lblTargetVolm.VerticalAlignment = VerticalAlignment.Top;
			lblTargetVolm.Padding = _PadThickness;
			lblTargetVolm.Margin = new Thickness(0, 0, 0, 0);
			gridTask.Children.Add(lblTargetVolm);
			
			if (CanEditTask)
            {
				lblTankName.MouseDoubleClick += EditTaskMenu_DblClick;
				lblTankName.Tag = task.TaskId;
				ContextMenu rmenu = new ContextMenu();
				MenuItem deleteMenu = new MenuItem();
				deleteMenu.Header = "删除";
				deleteMenu.Click += DeleteTaskMenu_Click;
				deleteMenu.Tag = task.TaskId;
				rmenu.Items.Add(deleteMenu);
				gridTask.ContextMenu = rmenu;
			}

            Border gridBorder = new Border();
            gridBorder.BorderThickness = new Thickness(1, 0, 1, 2);
            gridBorder.BorderBrush = _COTBorderBrush;
            gridTask.Children.Add(gridBorder);
            return gridTask;
        }

        private Grid CreateOutOrSwapTaskGrid(TankTask task)
        {
            double taskHours = (task.PlanEndTime - task.PlanStartTime).TotalHours;
            //计算任务宽度
            Grid gridTask = new Grid();
            gridTask.Width = canvas_2_0.ActualWidth / HourCount * taskHours;
            gridTask.Height = canvas_2_0.ActualHeight;
            gridTask.Background = task.TaskType == TaskTypeConstant.SWAP_ID ? _SwapTaskBodyBrush : _OutTaskBodyBrush;

            Label lblTankName = new Label();
            if (task.TaskType == TaskTypeConstant.SWAP_ID)
            {
                lblTankName.Content = TankConstant.GetTankName(task.TankId) + string.Format("({0}%)", task.TargetVolm) + " -> " + TankConstant.GetTankName(task.SwapTargetTank1);
            }
            else
            {
                lblTankName.Content = TankConstant.GetTankName(task.TankId) + string.Format("({0}%)", task.TargetVolm);
            }
            lblTankName.FontSize = 1.1 * FontSize;
            lblTankName.HorizontalAlignment = HorizontalAlignment.Center;
            lblTankName.VerticalAlignment = VerticalAlignment.Bottom;
            lblTankName.Margin = new Thickness(5, 0, 0, 2);
            lblTankName.Padding = _PadThickness;
            gridTask.Children.Add(lblTankName);

            Label lblStartTime = new Label();
            lblStartTime.Content = task.PlanStartTime.ToString("HH:mm");
            lblStartTime.FontSize = FontSize;
            lblStartTime.HorizontalAlignment = HorizontalAlignment.Left;
            lblStartTime.VerticalAlignment = VerticalAlignment.Top;
            lblStartTime.Padding = _PadThickness;
            lblStartTime.Margin = _StartTimeMargin;
            gridTask.Children.Add(lblStartTime);

            Label lblUseTime = new Label();
            lblUseTime.Content = string.Format("+{0:f1}H", taskHours);
            lblUseTime.FontSize = FontSize;
            lblUseTime.HorizontalAlignment = HorizontalAlignment.Right;
            lblUseTime.VerticalAlignment = VerticalAlignment.Top;
            lblUseTime.Padding = _PadThickness;
            lblUseTime.Margin = new Thickness(0, 0, 2, 0);
            gridTask.Children.Add(lblUseTime);

			//增加液货舱任务目标容积
			double volmValue = (task.TargetVolm / 100d) * TankConstant.GetTankVolume(task.TankId);
			Label lblTargetVolm = new Label();
			lblTargetVolm.Content = string.Format("{0:f1}M3", volmValue);
			lblTargetVolm.FontSize = FontSize;
			lblTargetVolm.HorizontalAlignment = HorizontalAlignment.Center;
			lblTargetVolm.VerticalAlignment = VerticalAlignment.Top;
			lblTargetVolm.Padding = _PadThickness;
			lblTargetVolm.Margin = new Thickness(0, 0, 0, 0);
			gridTask.Children.Add(lblTargetVolm);

            if (CanEditTask)
            {
                ContextMenu rmenu = new ContextMenu();
                MenuItem deleteMenu = new MenuItem();
                deleteMenu.Header = "删除";
                deleteMenu.Click += DeleteTaskMenu_Click;
                deleteMenu.Tag = task.TaskId;
                rmenu.Items.Add(deleteMenu);
                //MenuItem viewMenu = new MenuItem();
                //viewMenu.Header = "查看";
                //viewMenu.Click += ViewTaskMenu_Click;
                //viewMenu.Tag = task.TaskId;
                //rmenu.Items.Add(viewMenu);
                gridTask.ContextMenu = rmenu;
            }

            Border gridBorder = new Border();
            gridBorder.BorderThickness = new Thickness(1, 0, 1, 2);
            gridBorder.BorderBrush = _COTBorderBrush;
            gridTask.Children.Add(gridBorder);
            return gridTask;
        }

        private void DeleteTaskMenu_Click(object sender, RoutedEventArgs e)
        {
            // 鉴权操作
            if (!AuthUtil.IsHasPermission())
            {
				return;
            }
			if (MessageBox.Show("是否删除任务！", "确认", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                MenuItem menuItem = (MenuItem)sender;
                TaskService.DeleteTask(Convert.ToInt32(menuItem.Tag));
                ControlUpdate();
            }
        }
		private void EditTaskMenu_DblClick(object sender, RoutedEventArgs e)
		{
			// 鉴权操作
			if (!AuthUtil.IsHasPermission())
			{
				return;
			}
			Label label = (Label)sender;
			TankTask tankTask = TaskService.GetTask(Convert.ToInt32(label.Tag));
			TaskInfoView createView = new TaskInfoView(1, new DBTankTaskService());
			createView.InitTaskConent(tankTask);
			createView.ShowDialog();
			ControlUpdate();
		}

		private void ViewTaskMenu_Click(object sender, RoutedEventArgs e)
        {

        }

        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            startBackground.Fill = _btnSelectBrash;
            pauseBackground.Fill = _btnUnSelectBrash;
            //对应任务线上方菜单，用于启动任务模拟
            StartImitateAction?.Invoke(sender);
        }

        private void btnAddTask_Click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)sender;
            AddTaskAction?.Invoke(this, Convert.ToInt32(btn.Tag));
            ControlUpdate();
        }

        private void btnAutoTask_Click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)sender;
            AutoTaskAction?.Invoke(this, Convert.ToInt32(btn.Tag));
            ControlUpdate();
        }

        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            startBackground.Fill = _btnUnSelectBrash;
            pauseBackground.Fill = _btnSelectBrash;
            //对应任务线上方菜单，用于停止任务模拟
            Button btn = (Button)sender;
            PauseImitateAction?.Invoke(this, Convert.ToInt32(btn.Tag));
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            //对应任务线上方菜单，用于取消任务模拟
            double a = 0;
        }

        private void btnConfirm_Click(object sender, RoutedEventArgs e)
        {
            //对应任务线上方菜单，用于将当前任务用于实际作业
            Button btn = (Button)sender;
            SubmitTaskAction?.Invoke(this, Convert.ToInt32(btn.Tag));
        }

		internal void setClickBackground(bool running)
		{
			if (running) 
			{
				startBackground.Fill = _btnSelectBrash;
				pauseBackground.Fill = _btnUnSelectBrash;
			}
			else
			{
				startBackground.Fill = _btnUnSelectBrash;
				pauseBackground.Fill = _btnSelectBrash;
			}
		}
		private void btnDefineStatus_Click(object sender, RoutedEventArgs e)
		{
			Button btn = (Button)sender;
			DefineStatusAction?.Invoke(this, Convert.ToInt32(btn.Tag));
		}
	}
}
